package domain;

import foundation.TxtFileUtil;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.*;
import java.security.cert.Certificate;
import org.apache.commons.codec.binary.Base64;

public class CertificateHelper {
    private static final String KEY_STORE = "JKS";
    private static final String STORE_FILE_NAME="./src/main/resources/.keystore";
    /**
     * 生成数字签名证书
     *
     * @param input 生成证书需要输入的信息
     * @throws Exception
     */
    public void genCertificate(GenCertiInput input) throws Exception {
        String errMsg = input.check();//检查输入合法性
        if (errMsg != null) {
            throw new Exception(errMsg);
        }
        String cmdTxt = genCmdTxt(input);//获取生成证书的命令文本
        //delHasExistCert(input);//若证书已存在则删除
        execCmd(cmdTxt);//在Dos下执行命令文
    }

    /**
     * 获取证书存储KeyStore
     * @param name 证书别名
     * @param keyPsw 证书别名的密码
     * @return
     * @throws Exception
     */
    public KeyStore getKeyStore(String name, String keyPsw) throws Exception{
        KeyStore keyStore = KeyStore.getInstance("jks");
        FileInputStream fis = new FileInputStream(STORE_FILE_NAME);
        keyStore.load(fis, keyPsw.toCharArray());
        fis.close();
        return keyStore;
    }
    /**
     * 获取证书
     * @param name 证书别名
     * @param keyPsw 证书别名的密码
     * @return
     * @throws Exception
     */
    public Certificate getCertificate(String name, String keyPsw) throws Exception {
        KeyStore keyStore =getKeyStore(name,keyPsw);
        Certificate cert = keyStore.getCertificate(name);
        return cert;
    }
    /**
     * 获取证书中公钥
     * @param name 证书别名
     * @param keyPsw 证书别名的密码
     * @return
     * @throws Exception
     */
    public PublicKey getPublicKey(String name, String keyPsw) throws Exception {
        PublicKey publicKey = null;
        Certificate certificate=getCertificate(name,keyPsw);
        publicKey=certificate.getPublicKey();
        return publicKey;
    }
    /**
     * 获取证书私钥
     * @param name 证书别名
     * @param keyPsw 证书别名的密码
     * @return
     * @throws Exception
     */
    public PrivateKey getPrivateKey(String name, String keyPsw) throws Exception {
        KeyStore keyStore =getKeyStore(name,keyPsw);
        PrivateKey privateKey = (PrivateKey) keyStore.getKey(name, keyPsw.toCharArray());
        return privateKey;
    }

    /**
     * 获取证书公钥Base64字符串
     * @param name 证书别名
     * @param keyPsw 证书别名的密码
     * @return
     * @throws Exception
     */
    public String getStrPublicKey(String name, String keyPsw)
            throws Exception {
        PublicKey publicKey = getPublicKey( name, keyPsw);
        String strPublicKey = Base64.encodeBase64String(publicKey.getEncoded());
        return strPublicKey;
    }

    /**
     * 获取证书公钥Base64字符串
     * @param name 证书别名
     * @param keyPsw 证书别名的密码
     * @return
     * @throws Exception
     */
    public  String getStrPrivateKey(String name, String keyPsw) throws Exception {
        PrivateKey key = getPrivateKey(name, keyPsw);
        String strKey = Base64.encodeBase64String(key.getEncoded());
        return strKey;
    }

    /**
     * 生成证书时的命令文本
     *
     * @param input 生成证书时的输入
     * @return
     */
    public String genCmdTxt(GenCertiInput input) {
        String cmdTxt = "keytool -genkey -alias ";
        cmdTxt += input.getName().trim() + " ";
        cmdTxt += "-keypass " + input.getKeyPsw() + " ";
        cmdTxt += "-keyalg RSA -keysize 1024 ";
        cmdTxt += "-validity " + input.getDays() + " ";
        //String certiPath = input.getCertFilePath();
        cmdTxt += "-keystore " +STORE_FILE_NAME+" ";//+ certiPath + input.getName().trim() + ".keystore ";
        cmdTxt += "-storepass " + input.getStorePsw();
        return cmdTxt;
    }

    /*
    public void delHasExistCert(GenCertiInput input) {
        String certiPath = input.getCertFilePath();
        String certiFileName = certiPath + input.getName() + ".keystore";
        File certiFile = new File(certiFileName);
        if (certiFile.exists()) {
            certiFile.delete();
        }
    }*/


    /**
     * 执行Dos下命令文本
     *
     * @param cmdTxt 命令文本
     * @throws Exception
     */
    public void execCmd(String cmdTxt) throws Exception {
        Runtime run = Runtime.getRuntime();
        try {
            //run.exec("cmd /k shutdown -s -t 3600");
            String cmdFileName = "." + File.separator + "cmdTxt.bat";
            File cmdFile = new File(cmdFileName);
            TxtFileUtil.writeTxtFile(cmdTxt, cmdFile);
            Process process = run.exec("cmd.exe /k start " + cmdFileName);
            InputStream in = process.getInputStream();
            while (in.read() != -1) {
                System.out.println(in.read());
            }
            in.close();
            int exitVal = process.waitFor();
            System.out.println(exitVal);
        } catch (Exception e) {
            String errMsg = "执行证书生成命令时出错！\n";
            errMsg += e.getMessage();
            throw new Exception(errMsg);
        }
    }

    public static void main(String args[]) throws Exception {
        String basePath = "./src/test/java/domain/data/";

        GenCertiInput input = new GenCertiInput("tomcat2",
                "123456", 365, "123456");
        CertificateHelper helper = new CertificateHelper();
       String cmdTxt=helper.genCmdTxt(input);
      // helper.delHasExistCert(input);
       helper.execCmd(cmdTxt);
/*
        //PublicKey publicKey=helper.getPublicKey(basePath+"tomcat.keystore");
        Certificate certificate = helper.getCertificate("tomcat2", "123456");
        System.out.println(certificate.toString()); */
    }
}
